/**
 * Created by kc on 16/7/18.
 */


var logger      = require('./log.js').logger;
var co              = require('co');
var parseString = require('xml2js').parseString;
var tjs         = require('./t.js');
var ezhttps     = require('./ezhttp').ezhttps;
var mWx             = require('../busimodule/mWx.js');
var config 		= require('../conf/config.js');
var wxConfig    = config['wechat'];

exports.genPayJS = function (openid, outTradeNo, totalFee, attach, body){
    return function(cb) {
        wxPrepay({
            openid:openid, outTradeNo: outTradeNo, totalFee: totalFee, attach: attach, body: body, tradeType: 'JSAPI'
        }, function (res) {
            if (!res) {
                cb(null, res);
                return;
            }
            logger.debug('prepay res: '+JSON.stringify(res));
            var jsApiObj = [];
            var prepayId = res['prepay_id'];
            var appid = wxConfig['appid'];
            var timeStamp = (+new Date()).toString().substr(0, 10);

            jsApiObj["appId"] = appid;
            jsApiObj["timeStamp"] = timeStamp;
            jsApiObj["nonceStr"] = Math.random().toString(36).substr(2, 15);
            jsApiObj["package"] = "prepay_id=" + prepayId;
            jsApiObj["signType"] = "MD5";
            jsApiObj["paySign"] = wxSign(jsApiObj);

            cb(null, jsApiObj);
        });
    };
};

exports.genPayQrCode = function (outTradeNo, totalFee, attach, body)
{
    return function(cb) {
        wxPrepay({
            outTradeNo:outTradeNo, totalFee:totalFee, attach:attach, body:body
        },function(res){
            cb(null, res);
        });
    }
};

exports.payNotify = function(wxRes, orderInfo, wxXml) {
    return function (cb) {
        var sign = wxRes['sign'].toString().toUpperCase();
        wxRes['sign'] = ''; //sign不参与签名
        delete wxRes['sign'];

        if (sign != wxSign(wxRes)) {
            resMsg = 'sign error';
            logger.debug('wxres: sign error. ' + sign);
        } else {
            orderInfo['order_no'] = wxRes['out_trade_no'];
            orderInfo['device_info'] = wxRes['device_info']||'';
            orderInfo['err_msg'] = wxRes['err_code_des'] || wxRes['return_msg']||'';
            orderInfo['openid'] = wxRes['openid'];
            orderInfo['pay_fee'] = wxRes['total_fee'];
            orderInfo['pay_order_no'] = wxRes['transaction_id'];
            orderInfo['time_end'] = wxRes['time_end'];
            orderInfo['raw_data'] = wxXml;
            orderInfo['pay_type'] = orderInfo['pay_type'];
            orderInfo['pay_result'] = 2;
            if (orderInfo['order_fee'] != wxRes['total_fee']) {
                logger.error('orderno ' + wxRes['out_trade_no'] + ': 订单金额与支付金额不一致。');
                createCard = false;
            } else {
                createCard = true;
            }
            resCode = 'SUCCESS';
            resMsg = 'OK';
        }
        var resXml = _getResXml(resCode, resMsg);
        cb(null, {createCard: createCard, updateOrder: orderInfo, resStr: resXml});
    };
};

exports.getResXml = function(resCode, resMsg){
    return _getResXml(resCode, resMsg);
};

exports.parserXML = function(xml){
    return function(cb){
        _parseXml(xml, function(res){
            cb(null, res);
        });
    }
};

function wxSign(args) {
    var keys = Object.keys(args);
    keys = keys.sort();
    var newArgs = {};
    keys.forEach(function (key) {
        newArgs[key] = args[key];
    });

    var string = '';
    for (var k in newArgs) {
        if(newArgs[k]=='')continue;
        string += '&' + k + '=' + newArgs[k];
    }
    string = string.substr(1) + '&key='+wxConfig['appkey'];
    var sign = tjs.md5hash(string);
    logger.debug('test1 md5:'+tjs.md5hash("prepay_id=121212"));
    logger.debug('wx sign raw: '+string + '\n sign: '+sign);
    return sign.toUpperCase();
}

function _parseXml(xml, cb) {
    parseString(xml, function (err, result) {
        cb(err ? null : result);
    });
}

function _getResXml(resCode, resMsg){
    return '<xml><return_code><![CDATA[' + resCode + ']]></return_code><return_msg><![CDATA[' + resMsg + ']]></return_msg></xml>';
}

function wxPrepay(obj, cb){
    var url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    var appid = wxConfig['appid'];
    var mch_id = wxConfig['mchid'];
    var notify_url = wxConfig['notify_url'];
    var out_trade_no = obj.outTradeNo;
    var total_fee = obj.totalFee;
    var attach = obj.attach;
    var body = obj.body;
    var openid = obj.openid||'';
    var tradeType = obj.tradeType || 'NATIVE'; //JSAPI，NATIVE，APP
    var nonce_str = Math.random().toString(36).substr(2, 15);
    var sign = wxSign({
        appid: appid, attach: attach, body: body, mch_id: mch_id,
        nonce_str: nonce_str, notify_url:notify_url,  openid:openid,
        out_trade_no:out_trade_no, spbill_create_ip:'',
        total_fee:total_fee, trade_type:tradeType
    });
    var formData = "<xml>";
    formData += "<appid>" + appid + "</appid>"; //appid
    //formData += "<attach>" + attach + "</attach>"; //附加数据
    formData += "<body>" + body + "</body>"; //商品或支付单简要描述
    formData += "<mch_id>" + mch_id + "</mch_id>"; //商户号
    formData += "<nonce_str>" + nonce_str + "</nonce_str>"; //随机字符串，不长于32位
    formData += "<notify_url>" + notify_url + "</notify_url>"; //支付成功后微信服务器通过POST请求通知这个地址
    formData += "<openid>"+openid+"</openid>"; //扫码支付这个参数不是必须的
    formData += "<out_trade_no>" + out_trade_no + "</out_trade_no>"; //订单号
    //formData += "<spbill_create_ip></spbill_create_ip>"; //不是必须的
    formData += "<total_fee>" + total_fee + "</total_fee>"; //金额
    formData += "<trade_type>"+tradeType+"</trade_type>"; //NATIVE会返回code_url ，JSAPI不会返回
    formData += "<sign>" + sign + "</sign>";
    formData += "</xml>";

    logger.debug('postxml: '+ formData);
    ezhttps('api.mch.weixin.qq.com','POST','/pay/unifiedorder', {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'},formData,function(err,res){
        if(err) {
            logger.error(to_cellno+':微信预下单失败'+err.message);
            cb(null);
        } else {
            _parseXml(res, function(xmlObj){
                var wxRes = xmlObj ? xmlObj['xml'] : null;
                if(!wxRes || (wxRes['return_code']!='SUCCESS' && wxRes['result_code']!='SUCCESS')){
                    logger.debug('wx pay prepay error: '+res);
                    cb(null);
                    return;
                }
                cb(wxRes);
            });
        }
    });
}